#include<string>
#include <stdarg.h>
#include<iostream>
#include <sys/types.h>
#include <sys/stat.h>   
#include <sys/ipc.h>  
#include <sys/shm.h>    
#include<cstring>
#include <unistd.h>
#include <fcntl.h>

using namespace std; 

#define Screen     1
#define Onefile    2
#define Classfile  3

#define Info    0
#define Debug   1
#define Warning 2
#define Error   3
#define Fatal   4

#define SIZE 1024

#define Path "./log/"
#define File "log.txt"

class Log
{
public:
    Log(){
        path=Path;
        PrintMethod=Screen;
    }
    void Enable(int n){
        PrintMethod=n;
    }
    string LevelToString(int level){
        switch(level)
        {
        case Info:
            return "Info";
            break;
        case Debug:
            return "Info";
            break;
        case Warning:
            return "Warning";
            break;
        case Error:
            return "Error";
            break;
        case Fatal:
            return "Fatal";
            break;
        default:
            return "NONE";
            break;
        }
    }
/*     void logmessages(int level,const char *format,...)
    {
        time_t t=time(nullptr);
        struct tm *ctime=localtime(&t);//得到时间
        char leftbuffer[SIZE];
        snprintf(leftbuffer,sizeof(leftbuffer),"[%s][%d-%d-%d %d-%d-%d]",
                            LevelToString(level).c_str(),
                            ctime->tm_year+1900,ctime->tm_mon+1,ctime->tm_mday,
                            ctime->tm_hour,ctime->tm_min,ctime->tm_sec);
        char rightbuffer[SIZE];
        va_list s;
        va_start(s,format);
        vsnprintf(rightbuffer,sizeof(rightbuffer),format,s);
        va_end(s);
        char buffer[SIZE*2];
        snprintf(buffer,sizeof(buffer),"%s %s\n",leftbuffer,rightbuffer);
        PrintLog(level,buffer);
    } */
    void operator()(int level,const char *format,...)
    {
         time_t t=time(nullptr);
        struct tm *ctime=localtime(&t);//得到时间
        char leftbuffer[SIZE];
        snprintf(leftbuffer,sizeof(leftbuffer),"[%s][%d-%d-%d %d-%d-%d]",
                            LevelToString(level).c_str(),
                            ctime->tm_year+1900,ctime->tm_mon+1,ctime->tm_mday,
                            ctime->tm_hour,ctime->tm_min,ctime->tm_sec);
        char rightbuffer[SIZE];
        va_list s;
        va_start(s,format);
        vsnprintf(rightbuffer,sizeof(rightbuffer),format,s);
        va_end(s);
        char buffer[SIZE*3];
        snprintf(buffer,sizeof(buffer),"%s %s\n",leftbuffer,rightbuffer);
        PrintLog(level,buffer);
    }
    void PrintLog(int level,string s)
    {
        switch(PrintMethod){
            case Screen:
                cout<<s;
                break;
            case Onefile:
                 Printone(File,s);
                 break;
            case Classfile:
                  Printclass(level,s);
                  break;
        }
    }
    void Printone(const string& FILE,const string& s)
    {
        string file=path+FILE;
        int fd=open(file.c_str(),O_CREAT|O_WRONLY|O_APPEND,0666);
        if(fd<0){
            perror("open");
            exit(0);
        }
        write(fd,s.c_str(),s.size());
    }
    void Printclass(int level,const string& s)
    {
        string _file=File;
        _file+=('.'+LevelToString(level));
        Printone(_file,s);
    }
    ~Log(){}

private:
    string path;
    int PrintMethod;
};